package com.winit.openapi.fna.controller;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import com.alibaba.fastjson.JSONObject;
import com.winit.common.query.Page;
import com.winit.common.query.SearchOperator;
import com.winit.common.query.Searchable;
import com.winit.common.query.filter.SearchFilterHelper;
import com.winit.common.spi.context.CommandContext;
import com.winit.common.utils.Dates;
import com.winit.erp.spi.common.BankAccountService;
import com.winit.erp.spi.common.command.BankAccountCommand;
import com.winit.erp.spi.common.vo.BankAccount;
import com.winit.fna.spi.recharge.OfflineRechargeService;
import com.winit.fna.spi.recharge.command.AddOfflineRechargeCommand;
import com.winit.fna.spi.recharge.command.QueryRechargePageCommand;
import com.winit.fna.spi.recharge.command.UpdateOfflineRechargeCommand;
import com.winit.fna.spi.recharge.vo.OfflineRecharge;
import com.winit.fsp.spi.customer.CustomerService;
import com.winit.fsp.spi.customer.command.QueryCustomerByIdCommand;
import com.winit.fsp.spi.customer.vo.Customer;
import com.winit.openapi.constants.ApiConstant;
import com.winit.openapi.constants.ErrorCode;
import com.winit.openapi.controller.BaseController;
import com.winit.openapi.exception.ApiException;
import com.winit.openapi.model.RequestMsg;
import com.winit.openapi.model.ResponseMsg;
import com.winit.openapi.util.CtxUtil;
import com.winit.openapi.util.ValidateUtil;

/**
 * FNA 线下充值单
 * 
 * @author
 * @since 1.0
 */
@Controller
@RequestMapping(value = "/fna/recharge")
public class OfflineRechargeController extends BaseController {

    @Resource
    private OfflineRechargeService    offlineRechargeService;

    @Resource
    private CustomerService           customerService;

    @Resource
    private BankAccountService        bankAccountService;

    public static Map<String, String> Status_map = new HashMap<String, String>();
    static {
        Status_map.put("CFI", "已提交");
        Status_map.put("SU", "付款成功");
        Status_map.put("ER", "付款失败");
        Status_map.put("VO", "作废");
    }

    /**
     * 新增充值单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/addOfflineRecharge")
    public String addOfflineRecharge(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        AddOfflineRechargeCommand command = null;
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            command = JSONObject.toJavaObject(json, AddOfflineRechargeCommand.class);
            CommandContext ctx = CommandContext.getContext();
            command.setCtx(ctx);
            // 根据前台传入客户ID查询客户信息
            QueryCustomerByIdCommand cstomerCommand = new QueryCustomerByIdCommand();
            cstomerCommand.setId(command.getCustomerId());
            Customer customer = customerService.queryCustomerById(cstomerCommand);
            if (customer != null) {
                command.setCustomerName(customer.getCustomerNameEn());
            }
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        offlineRechargeService.addOfflineRecharge(command);
        return SUCCESS;
    }

    /**
     * 修改充值单状态
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/updateRechargeStatus")
    public String updateRechargeStatus(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        UpdateOfflineRechargeCommand command = null;

        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            command = JSONObject.toJavaObject(json, UpdateOfflineRechargeCommand.class);
            CommandContext ctx = CommandContext.getContext();
            command.setCtx(ctx);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        // 调用接口更新信息
        offlineRechargeService.updateOfflineRecharge(command);
        return SUCCESS;
    }

    /**
     * 查询线下充值单列表（分页）
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     * @author
     * @date 2015-4-03
     */
    @RequestMapping(value = "queryRechargePageByCondition")
    public String queryRechargePageByCondition(@ModelAttribute RequestMsg requestMsg,
                                               @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        QueryRechargePageCommand command = null;
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            validpageParams(json);
            command = JSONObject.toJavaObject(json, QueryRechargePageCommand.class);
            Searchable searchable = buildSearchPageParams(json);
            if (StringUtils.isNotBlank(json.getString("remitStartDate"))) {
                if (json.containsKey("remitStartDate")) {
                    Date remitStartDate = CtxUtil.getRealDate(json.getDate("remitStartDate"));
                    searchable.and(SearchFilterHelper.newCondition("REMIT_DATE", SearchOperator.gte, remitStartDate));
                }
                if (json.containsKey("remitEndDate")) {
                    Calendar rightNow = Calendar.getInstance();
                    rightNow.setTime(json.getDate("remitEndDate"));
                    rightNow.add(Calendar.DAY_OF_YEAR, 1);// 日期加1天
                    Date dt1 = rightNow.getTime();
                    Date remitEndDate = CtxUtil.getRealDate(dt1);
                    searchable.and(SearchFilterHelper.newCondition("REMIT_DATE", SearchOperator.lte, remitEndDate));
                }
            }
            if (StringUtils.isNotBlank(json.getString("applyStartDate"))) {
                if (json.containsKey("applyStartDate")) {
                    Date applyStartDate = CtxUtil.getRealDate(json.getDate("applyStartDate"));
                    searchable.and(SearchFilterHelper.newCondition("APPLY_DATE", SearchOperator.gte, applyStartDate));
                }
                if (json.containsKey("applyEndDate")) {
                    Date applyEndDate = CtxUtil.getFullDate(json.getDate("applyEndDate"));
                    searchable.and(SearchFilterHelper.newCondition("APPLY_DATE", SearchOperator.lte, applyEndDate));
                }
            }
            if (json.containsKey("status")) {
                String status = json.getString("status");
                if (status != null && !status.equals("null") && !"".equals(status)) {
                    searchable.and(SearchFilterHelper.newCondition("STATUS",
                        SearchOperator.eq,
                        json.getString("status")));
                }
            }
            if (json.containsKey("customerId")) {
                searchable.and(SearchFilterHelper.newCondition("CUSTOMER_ID",
                    SearchOperator.eq,
                    json.getString("customerId")));
            }
            command.setSearchable(searchable);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        command.setCtx(CommandContext.getContext());
        // 调用接口分页查询金融商品
        Page<OfflineRecharge> pagelist = offlineRechargeService.queryOfflineRechargePage(command);
        if (pagelist != null) {
            Map<Long, BankAccount> map = getBankAccount();
            for (OfflineRecharge offlineRecharge : pagelist.getContent()) {
                BankAccount bankAccount = map.get(offlineRecharge.getBankAccountId());
                if (bankAccount != null) {
                    offlineRecharge.setBankAccountName(bankAccount.getBankAccountNo());
                    offlineRecharge.setStatusName(Status_map.get(offlineRecharge.getStatus()));
                }
            }
            Map<String, Object> pageMap = new HashMap<String, Object>();
            pageMap.put("pageNo", pagelist.getPageable().getPageNumber() + 1);
            pageMap.put("pageSize", pagelist.getPageable().getPageSize());
            pageMap.put("totalCount", pagelist.getTotalElements());

            Map<String, Object> data = new HashMap<String, Object>();
            data.put("list", pagelist.getContent());
            data.put("pageParams", pageMap);
            responseMsg.setData(data);
        }
        return SUCCESS;
    }

    public Map<Long, BankAccount> getBankAccount() {
        Map<Long, BankAccount> map = new HashMap<Long, BankAccount>();
        BankAccountCommand command = new BankAccountCommand();
        command.setCurrencyCode("USD");
        List<BankAccount> bankList = bankAccountService.findBankAccount(command);
        for (int i = 0; i < bankList.size(); i++) {
            map.put(bankList.get(i).getBankAccountId(), bankList.get(i));
        }
        return map;
    }

    private void validpageParams(JSONObject json) {
        // pageParams
        if (json.containsKey("pageParams")) {
            Object obj = json.get("pageParams");
            if (obj instanceof JSONObject) {
                JSONObject pageParams = (JSONObject) obj;
                // pageNo
                ValidateUtil.validInteger(pageParams, "pageNo");
                // pageSize
                ValidateUtil.validInteger(pageParams, "pageSize");
                if (pageParams.containsKey("pageNo")) {
                    int pageNo = pageParams.getInteger("pageNo");
                    if (pageNo < 1) {
                        throw new ApiException(ErrorCode.FIELD_ERROR, "pageNo");
                    }
                }
                if (pageParams.containsKey("pageSize")) {
                    int pageSize = pageParams.getInteger("pageSize");
                    if (pageSize < 1) {
                        throw new ApiException(ErrorCode.FIELD_ERROR, "pageSize");
                    }
                }
            } else {
                throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "pageParams");
            }
        }
    }

    private Searchable buildSearchPageParams(JSONObject json) {
        int pageNo = ApiConstant.PAGE_NO_DEFAULT;
        int pageSize = ApiConstant.PAGE_SIZE_DEFAULT;
        // pageParams
        if (json != null && json.containsKey("pageParams")) {
            JSONObject pageParams = json.getJSONObject("pageParams");
            // pageNo
            if (pageParams.containsKey("pageNo")) {
                pageNo = pageParams.getInteger("pageNo");
            }
            // pageSize
            if (pageParams.containsKey("pageSize")) {
                pageSize = pageParams.getInteger("pageSize");
            }
        }
        Searchable search = Searchable.newSearchable();
        search.setPage(pageNo - 1, pageSize);

        return search;
    }

    /**
     * 获取日期所在当前的最大值 ，如2010-7-27 23:59:59.000
     * 
     * @param date
     * @return
     */
    public static Date getFullDate(Date date) {
        GregorianCalendar gc = new GregorianCalendar();
        gc.setTimeInMillis(date.getTime());
        gc.set(GregorianCalendar.HOUR_OF_DAY, 23);
        gc.set(GregorianCalendar.MINUTE, 59);
        gc.set(GregorianCalendar.SECOND, 59);
        gc.set(GregorianCalendar.MILLISECOND, 0);
        return new Date(gc.getTimeInMillis());
    }

    public static Date getUtcFullDate(Date utcDate) {
        Date startLocal = Dates.getLocalDate(utcDate);
        Date start = getFullDate(startLocal);
        Date startUtc = Dates.getUTCDate(start);
        return startUtc;
    }
}
